/////////////////////////////////////////////////////////////////////////////
// Name:        ax_textctrl.h
// Purpose:     Accessibility classes: AxTextCtrl (speaking text control)
// Author:      Julian Smart
// Modified by:
// Created:     2009-03-20
// RCS-ID:
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _AX_TEXTCTRL_H_
#define _AX_TEXTCTRL_H_

#include "wx/textctrl.h"
#include "ax/ax_speech.h"
#include "ax/ax_ui_adaptation.h"

class AxTextCtrlAdapter;
class AxSpeech;
class wxShortcutManager;

enum { AxTextCtrlNext = 0x01,
       AxTextCtrlPrevious = 0x02
};

/**
    @class AxTextCtrl

    A speaking version of wxTextCtrl.

    @category{ax}
 */

class AxTextCtrl: public wxTextCtrl
{
    DECLARE_DYNAMIC_CLASS( AxTextCtrl )

public:
// Constructors

    AxTextCtrl(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& value = wxEmptyString,
        const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
        int style = 0)
    {
        Init();
        Create(parent, id, value, pos, size, style);
    }

    AxTextCtrl() { Init(); }
    ~AxTextCtrl();

    bool Create(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& value = wxEmptyString,
        const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
        int style = 0);

// Operations

    void Init();

    AxTextCtrlAdapter* GetTextEventHandler() const { return m_textEventHandler; }
    void SetTextEventHandler(AxTextCtrlAdapter* handler) { m_textEventHandler = handler; }

    void SetShortcutManager(wxShortcutManager* shortcutManager);
    wxShortcutManager* GetShortcutManager() const;

    void SetSpeech(AxSpeech* speech);
    AxSpeech* GetSpeech() const;

protected:

    AxTextCtrlAdapter* m_textEventHandler;
};

/**
    @class AxTextCtrlAdapter

    An event handler that processes events from a wxTextCtrl
    and speaks, as appropriate.

    @category{ax}
 */

class AxTextCtrlAdapter: public AxAdapter
{
    DECLARE_DYNAMIC_CLASS( AxTextCtrlAdapter )
    DECLARE_EVENT_TABLE()

public:
// Constructors

    AxTextCtrlAdapter(wxTextCtrlBase* ctrl = NULL, AxSpeech* speech = NULL)
    {
        Init();

        m_textCtrl = ctrl;
        if (speech)
            SetSpeech(speech);
    }

    ~AxTextCtrlAdapter();

// Operations

    void Init();

// Overrides

    /// Override to return the name of the control.
    virtual wxString GetName();

    /// Override to return text representing the state of the control,
    /// for example the current value.
    virtual wxString GetStateText(AxContentLevel level);

    /// Get content
    virtual wxString GetContent(AxContentLevel level);

    /// Override to return the label for the control.
    virtual wxString GetLabel() { return GetStaticLabel(); }

    /// Update the appearance - text size, background, etc.
    virtual bool UpdateAppearance(int hints);

// New functions

    /// Read the current sentence.
    virtual bool ReadCurrentSentence();

    /// Read the next sentence.
    virtual bool ReadNextSentence();

    /// Read the previous sentence.
    virtual bool ReadPreviousSentence();

    /// Read the current paragraph.
    virtual bool ReadCurrentParagraph();

    /// Read the previous paragraph.
    virtual bool ReadPreviousParagraph();

    /// Read the next paragraph.
    virtual bool ReadNextParagraph();

    /// Read the current word.
    virtual bool ReadCurrentWord();

    /// Read the previous word.
    virtual bool ReadPreviousWord();

    /// Read the next word.
    virtual bool ReadNextWord();

    /// Spell the current word.
    virtual bool SpellWord();

    /// Read from the current position.
    virtual bool ReadFromCurrentPosition();

    /// Read from the start.
    virtual bool ReadFromStart();

    /// Describe current context.
    virtual bool DescribeContext();

    void SetTextCtrl(wxTextCtrlBase* ctrl) { m_textCtrl = ctrl; }
    wxTextCtrlBase* GetTextCtrl() const { return m_textCtrl; }

    bool GetWord(long currentPos, long& from, long& to, wxString& value);
    bool GetSentence(long currentPos, long& from, long& to, wxString& value);
    bool GetParagraph(long currentPos, long& from, long& to, wxString& value);

    long FindNextWordPosition(long currentPos, int direction);
    long FindNextSentencePosition(long currentPos, int direction);
    long FindNextParagraphPosition(long currentPos, int direction);

    bool EatWhitespace(long& pos);

    wxChar GetChar(long pos);

    void OnReadCurrentWord(wxCommandEvent& event);
    void OnReadNextWord(wxCommandEvent& event);
    void OnReadPreviousWord(wxCommandEvent& event);
    void OnReadCurrentSentence(wxCommandEvent& event);
    void OnReadNextSentence(wxCommandEvent& event);
    void OnReadPreviousSentence(wxCommandEvent& event);
    void OnReadCurrentParagraph(wxCommandEvent& event);
    void OnReadNextParagraph(wxCommandEvent& event);
    void OnReadPreviousParagraph(wxCommandEvent& event);
    void OnReadFromHere(wxCommandEvent& event);
    void OnReadAll(wxCommandEvent& event);

    void OnDescribeContext(wxCommandEvent& event);

protected:

    wxTextCtrlBase*     m_textCtrl;
};

/**
    @class AxSearchCtrlAdapter

    An event handler that processes events from a wxSearchCtrl
    and speaks, as appropriate.

    @category{ax}
 */

class wxSearchCtrl;

class AxSearchCtrlAdapter: public AxTextCtrlAdapter
{
    DECLARE_DYNAMIC_CLASS( AxSearchCtrlAdapter )
    DECLARE_EVENT_TABLE()

public:
// Constructors

    AxSearchCtrlAdapter() {}

// Overrides

    /// Override to return the name of the control.
    virtual wxString GetName();

    /// Override to return text representing the state of the control,
    /// for example the current value.
    virtual wxString GetStateText(AxContentLevel level);

    /// Get content
    virtual wxString GetContent(AxContentLevel level);

    /// Override this if the adapter's actual window might not be the top-level control
    /// (may be the case for composite controls).
    virtual wxWindow* GetMainControl() const;

// New functions

    void OnCommand(wxCommandEvent& event);

    wxSearchCtrl* GetSearchCtrl() const;

protected:
};

/**
    @class AxTextCtrlVoiceAdaptationHandler

    Knows how to creates an AxTextCtrlAdapter object.

    @category{ax}
 */

class AxTextCtrlVoiceAdaptationHandler: public AxVoiceAdaptationHandler
{
    DECLARE_DYNAMIC_CLASS( AxTextCtrlVoiceAdaptationHandler )

public:
    AxTextCtrlVoiceAdaptationHandler() {}

    /// Override to indicate if this kind of window can be handled by this object.
    virtual bool CanHandleWindow(wxWindow* win);

    /// Override to create the event handler (but not push it onto the event stack)
    virtual AxAdapter* CreateEventHandler(wxWindow* win);

    /// Override to adapt e.g. a composite control. Returns an array of the identifiers
    /// of the adapted windows.
    virtual bool Adapt(wxWindow* window, AxSpeech* speech, wxShortcutManager* shortcuts, wxArrayInt& ids);

    /// Override to unadapt e.g. a composite control. Removes the id from ids once unadapted.
    virtual bool Unadapt(wxWindow* window, wxArrayInt& ids);

    /// Override to prevent recursive adaptation, e.g. into a composite.
    virtual bool CanRecursivelyAdapt(wxWindow* window) const;
};


#endif
    // _AX_TEXTCTRL_H_
